#include "graph.h"
#include<bits/stdc++.h>
using namespace std;
const int N = 204;
const int M = 40005;
struct Edge{
    int to, nxt, idx;
}edge[M<<1];
int h[N], cnt = 1;
void _add(int u, int v, int idx){
    edge[++cnt] = {v, h[u], idx};
    h[u] = cnt;
}
void add(int u, int v, int idx){
    _add(u, v, idx), _add(v, u, idx);
}
int val[N];
int deg[N];
int vis[N][N];
int idx;
struct Info{
    int have, from, to;
}info[N][N];
struct AtoAddEdge{
    int from, to;
}atoaddedge[M];
int addlen=0;
void dfs(){
    int x = ++idx;
    val[x] = 2;
    deg[x] = NumberOfRoads();
    int pre = LastRoad();
    if(pre != -1){
        vis[x][pre] = 1;
    }
    for(int i=1;i<=deg[x];i++){
        Move(i, 2);
        if(Color() == 2){
            int lst = LastRoad();
            Move(lst, 2);
        }else{
            info[x][i] = {1, x, idx+1};
            vis[x][i] = 1;
            add(x, idx+1, i);
            dfs();
        }
    }
    if(pre != -1) Move(pre, 2);
}

int tofind(int x){
    int col = Color();
    if(col == 3){
        return x;
    }
    for(int i=h[x];i;i=edge[i].nxt){
        int v = edge[i].to;
        int id = edge[i].idx;
        Move(id, 2);
        int lste = LastRoad();
        int ans = tofind(v);
        Move(lste, 2);
        if(ans) return ans;
    }
}

void refind(int x){

    for(int i=1;i<=deg[x];i++){
        if(!vis[x][i]){
            Move(i, 2);
            int lst = LastRoad();
            Move(lst, 3);
            int to = tofind(x);
            atoaddedge[++addlen] = {x, to};
        }
    }

    for(int i=h[x];i;i=edge[i].nxt){
        int v  =edge[i].to;
        int id = edge[i].idx;
        Move(id, 2);
        int lste = LastRoad();
        refind(v);
        Move(lste, 2);
    }
}


void process(){
    for(int i=1;i<=addlen;i++){
        _add(atoaddedge[i].from, atoaddedge[i].to, 0);
    }
}
int ans[N];
int dis[N];
struct Node{
    int dis, point;
};
bool operator < (Node xx, Node yy){
    return xx.dis < yy.dis;
}
bool operator > (Node xx, Node yy){
    return xx.dis > yy.dis;
}
int n;
void dijkstra(int x){
    memset(dis, 0, sizeof dis);
    priority_queue<Node, vector<Node>, greater<Node> >q;
    dis[x] = 0;
    q.push({x, 0});
    bool vvis[N];
    while(!q.empty()){
        Node u = q.top();
        q.pop();
        if(vis[u.point]) break;
        for(int i=h[u.point];i;i=edge[i].nxt){
            int v = edge[i].to;
            if(dis[v] > dis[u.point] + 1){
                dis[v] = dis[u.point] + 1;
                if(!vis[v]) q.push({dis[v], v});
            }
        }
    }

    for(int i=1;i<=n;i++){
        ans[dis[i]] ++;
    }

}
void init(){
    for(int i=1;i<N;i++){
        val[i] = 1;
    }
    dfs();
    n = idx;
    refind(1);
    process();
    for(int i=1;i<=n;i++){
        dijkstra(i);
    }
}

void Inspect(int R){
    init();
    for(int i=1;i<=R;i++){
        Answer(i, ans[i]);
    }
}